package zhai.docking.alipay.util;

import org.springframework.beans.BeanUtils;
import org.springframework.util.ObjectUtils;

import java.beans.PropertyDescriptor;
import java.util.*;

/**
 * @package: zhai.docking.alipay.util
 * @project-name: zhai-docking-alipay
 * @description: 对象工具类
 * @author: Created by 翟凤玺
 * @create-datetime: 2018-7-23 13:16
 */
public class ObjectUtil {
    /**
     * 对象是否为空
     */
    public static Boolean isNull(Object obj) {
        return ObjectUtils.isEmpty(obj);
    }

    /**
     * 对象不为空
     */
    public static Boolean isNotNull(Object obj) {
       return !ObjectUtil.isNull(obj);
    }

    /**
     * 对象拷贝
     * @param source 资源
     * @param classType 类型（除基本类型）
     */
    public static <T, E> E copy(T source, Class<E> classType) {

        if (source == null) {
            return null;
        }
        E targetInstance = null;
        try {
            targetInstance = classType.newInstance();
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        BeanUtils.copyProperties(source, targetInstance);
        return targetInstance;
    }

    /**
     * 集合拷贝
     * @param sourceList 资源集合
     * @param classType 类型（除基本类型）
     */
    public static <T, E> List<E> batchCopy(List<T> sourceList, Class<E> classType) {
        if (sourceList == null) {
            return null;
        }
        List<E> result = new ArrayList<E>();
        int size = sourceList.size();
        for (int i = 0; i < size; i++) {
            result.add(ObjectUtil.copy(sourceList.get(i), classType));
        }
        return result;
    }

    /**
     * 复制实体
     * @param source 资源
     * @param target 目标
     */
    public static void copy(Object source, Object target) {
        BeanUtils.copyProperties(source, target);
    }

    /**
     * 比较实体
     * @param source 资源
     * @param target 目标
     */
    public static boolean equals(Object source, Object target) {
        return Objects.equals(source, target);
    }

    /**
     * 对象比较
     */
    private static final String DIFFER_BEFORE = "before";
    private static final String DIFFER_AFTER = "after";
    /** key后缀 */
    private static final String DIFFER_KEY_SUFFIX = "Differ";
    /** 相同值 */
    private static final String DIFFER_VALUE_EQUAL = "equal";
    /** 不同值 */
    private static final String DIFFER_VALUE_DIFFER = "differ";

    public static Map<String, Object> compare(Object before, Object after) {
        if (ClassUtil.compareClass(before, after)) {
            Map<String, Object> result = new HashMap<>(2);
            PropertyDescriptor[] pds = ClassUtil.getClassProperty(before.getClass());
            Integer mapSize = pds.length * 2;
            Map<String, Object> beforeMap = new LinkedHashMap<>(mapSize);
            Map<String, Object> afterMap = new LinkedHashMap<>(mapSize);
            for (PropertyDescriptor pd : pds) {
                String key = ClassUtil.getPropertyName(pd);
                String differKey = StringUtil.join(key, DIFFER_KEY_SUFFIX);
                Object beforeValue = ClassUtil.getPropertyValue(pd, before);
                Object afterValue = ClassUtil.getPropertyValue(pd, after);
                beforeMap.put(key, beforeValue);
                afterMap.put(key, afterValue);
                //以下代码需要优化：判断当前属性的类型是否是String类型，如果是String类型并且值为null 则赋值""
                Object propertyType = ClassUtil.getPropertyType(pd);
                if ("class java.lang.String".equals(propertyType.toString())) {
                    if (beforeValue == null) {
                        beforeValue = "";
                    } else {
                        beforeValue = StringUtil.trimAllSpace(beforeValue.toString());
                    }
                    if (afterValue == null) {
                        afterValue = "";
                    } else {
                        afterValue = StringUtil.trimAllSpace(afterValue.toString());
                    }
                }
                if ("class java.lang.Integer".equals(propertyType.toString())) {
                    if (beforeValue == null) {
                        beforeValue = 0;
                    }
                    if (afterValue == null) {
                        afterValue = 0;
                    }
                }
                //优化截止
                if (beforeValue.equals(afterValue)) {
                    beforeMap.put(differKey, DIFFER_VALUE_EQUAL);
                    afterMap.put(differKey, DIFFER_VALUE_EQUAL);
                } else {
                    beforeMap.put(differKey, DIFFER_VALUE_DIFFER);
                    afterMap.put(differKey, DIFFER_VALUE_DIFFER);
                }
            }
            result.put(DIFFER_BEFORE, beforeMap);
            result.put(DIFFER_AFTER, afterMap);
            return result;
        }
        return null;
    }

}
